use crate::{config, message};
use futures::{AsyncBufReadExt, StreamExt, TryStreamExt};
use std::time::Duration;
use tokio::time;
use tracing::{error, info};

pub async fn connect_sse(url: &str) -> anyhow::Result<()> {
    let client = reqwest::Client::new();
    let mut retry_count = 0;
    const MAX_RETRIES: u32 = 5;
    const RETRY_DELAY: u64 = 90; // seconds

    info!("初始化SSE指数级退避：MAX_RETRIES = {},RETRY_DELAY = {}", MAX_RETRIES, RETRY_DELAY);

    loop {
        let resp = client.get(&format!("{}?code={}", url, config::get_device_code()?))
            .header("Accept", "text/event-stream")
            .send().await;

        info!("{}", &format!("发起SSE链接地址url: {}{:?}", url, config::get_device_code()));

        match resp {
            Ok(resp) => {
                let stream = resp.bytes_stream();
                let mut read = stream.map(|item| item.map_err(|_| std::io::Error::from(std::io::ErrorKind::Other))).into_async_read();
                let mut buf = String::new();
                // 处理SSE消息
                while read.read_line(&mut buf).await? != 0 {
                    if let Some((event, data)) = parse_sse_line(&buf) {
                        match event {
                            "data" => {
                                match serde_json::from_str::<message::Message>(data) {
                                    Ok(mut msg) => {
                                        msg.notification()?;
                                    },
                                    Err(_e) => {}
                                }
                            },
                            _ => {}
                        }
                    }
                    buf.clear();
                }
            },
            Err(err) => {
                error!("链接SSE失败{:?}", err);
                retry_count += 1;
                if retry_count >= MAX_RETRIES {
                    error!("已达最大重试次数...");
                    break;
                }
            }
        }

        retry_count += 1;
        if retry_count >= MAX_RETRIES {
            error!("已达最大重试次数...");
            break;
        }
        error!("链接失败，将于 {} 秒后重试.", RETRY_DELAY);
        time::sleep(Duration::from_secs(RETRY_DELAY)).await;
    }
    Ok(())
}

fn parse_sse_line(line: &str) -> Option<(&str, &str)> {
    let mut parts = line.splitn(2, ':');
    let event = parts.next()?.trim();
    let data = parts.next()?.trim();
    Some((event, data))
}
